/**
 * DataCleaner (community edition)
 * Copyright (C) 2014 Free Software Foundation, Inc.
 * <p>
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 * <p>
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 * <p>
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.datacleaner.panels;

import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;

import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.datacleaner.Version;
import org.datacleaner.actions.OpenAnalysisJobActionListener;
import org.datacleaner.actions.OpenDataCleanerWebsiteActionListener;
import org.datacleaner.guice.DCModule;
import org.datacleaner.user.UserPreferences;
import org.datacleaner.util.*;
import org.datacleaner.widgets.OpenAnalysisJobMenuItem;
import org.datacleaner.widgets.PopupButton;
import org.datacleaner.widgets.PopupButton.MenuPosition;
import org.datacleaner.windows.AnalysisJobBuilderWindow;
import org.datacleaner.windows.AnalysisJobBuilderWindow.AnalysisWindowPanelType;
import org.jdesktop.swingx.JXEditorPane;
import org.jdesktop.swingx.VerticalLayout;
import org.jdesktop.swingx.action.OpenBrowserAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Strings;
import com.google.common.net.UrlEscapers;
import com.google.inject.Injector;

/**
 * The initial panel that is shown to the user when starting the application. This panel features a pluggable content
 * part (see {@link SystemProperties#UI_DESKTOP_WELCOME_PANEL} and a button panels where a new job can be started, an
 * existing job can be opened and datastores can be managed.
 * 启动应用程序时显示给用户的初始面板。
 * 该面板具有可插拔内容部分（请参见{@link SystemProperties＃UI_DESKTOP_WELCOME_PANEL}）
 * 和按钮面板，可以在其中启动新作业，可以打开现有作业并可以管理数据存储。
 */
public class WelcomePanel extends DCSplashPanel {

	private static final Logger logger = LoggerFactory.getLogger(WelcomePanel.class);
	private static final WidgetScreenResolutionAdjuster adjuster = WidgetScreenResolutionAdjuster.get();

	private static final long serialVersionUID = 1L;

	private final UserPreferences _userPreferences;
	private final OpenAnalysisJobActionListener _openAnalysisJobActionListener;
	private final DCModule _dcModule;
	private final JComponent _buttonPanel;
	private final JComponent _titleLabel;

	public WelcomePanel(final AnalysisJobBuilderWindow window, final UserPreferences userPreferences,
						final OpenAnalysisJobActionListener openAnalysisJobActionListener, final DCModule dcModule) {
		super(window);
		_userPreferences = userPreferences;
		_openAnalysisJobActionListener = openAnalysisJobActionListener;
		_dcModule = dcModule;

		_titleLabel = createTitleLabel(PropertyUtil.getProperty("datacleaner.ui.desktop.text.welcome"), false);
		_buttonPanel = createButtonPanel();

		final JComponent contentPanel = createContentPanel();

		setLayout(new BorderLayout());
		add(_titleLabel, BorderLayout.NORTH);
		add(contentPanel, BorderLayout.CENTER);
		add(_buttonPanel, BorderLayout.SOUTH);
	}

	public JComponent getButtonPanel() {
		return _buttonPanel;
	}

	public JComponent getTitleLabel() {
		return _titleLabel;
	}

	private JComponent createContentPanel() {
		JComponent result = null;

		final String welcomePanelClassName =
				SystemProperties.getString(SystemProperties.UI_DESKTOP_WELCOME_PANEL, null);
		if (!Strings.isNullOrEmpty(welcomePanelClassName)) {
			final Injector injector = _dcModule.createInjectorBuilder().with(WelcomePanel.class, this).createInjector();
			try {
				@SuppressWarnings("unchecked") final Class<? extends JComponent> componentClass =
						(Class<? extends JComponent>) Class.forName(welcomePanelClassName);

				result = injector.getInstance(componentClass);
			} catch (final Exception e) {
				logger.error("Failed to instantiate welcome panel class: {}", welcomePanelClassName, e);
			}
		}

		if (result == null) {
			result = new DCPanel();
			if (Version.isCommunityEdition()) {
				final JXEditorPane editorPane = new JXEditorPane("text/html",
						PropertyUtil.getProperty("datacleaner.ui.desktop.text.Description"));
				editorPane.setEditable(false);
				editorPane.setOpaque(false);
				editorPane.setFont(WidgetUtils.FONT_HEADER2);
				editorPane.setPreferredSize(new Dimension(DCSplashPanel.WIDTH_CONTENT, adjuster.adjust(120)));

				final JButton tryProfessionalButton =
						WidgetFactory.createDefaultButton(PropertyUtil.getProperty("datacleaner.ui.desktop.canvas.try.pfofessional.edition"), IconUtils.APPLICATION_ICON);
				tryProfessionalButton.addActionListener(new OpenBrowserAction(
						"https://www.quadient.com/products/quadient-datacleaner#get-started-today"));

				final JButton discussionForumButton =
						WidgetFactory.createDefaultButton(PropertyUtil.getProperty("datacleaner.ui.desktop.canvas.visit.discussion.forum"), "images/menu/forum.png");
				discussionForumButton
						.setToolTipText(PropertyUtil.getProperty("datacleaner.ui.desktop.canvas.visit.discussion.forum.Description"));
				final OpenDataCleanerWebsiteActionListener forumActionListener =
						new OpenDataCleanerWebsiteActionListener("/discuss");
				discussionForumButton.addActionListener(forumActionListener);

				final JButton twitterButton = WidgetFactory.createDefaultButton(null, "images/menu/twitter.png");
				twitterButton.setToolTipText(PropertyUtil.getProperty("datacleaner.ui.desktop.canvas.visit.twitter"));
				twitterButton.addActionListener(new OpenBrowserAction("https://twitter.com/intent/tweet?text="
						+ UrlEscapers.urlFormParameterEscaper().escape("I'm using @DataCleaner (v. "
						+ Version.getVersion() + ") for some really fancy #dataquality stuff!")));

				final JButton linkedInButton = WidgetFactory.createDefaultButton(null, "images/menu/linkedin.png");
				linkedInButton.setToolTipText(PropertyUtil.getProperty("datacleaner.ui.desktop.canvas.visit.in"));
				linkedInButton.addActionListener(new OpenBrowserAction("http://www.linkedin.com/groups?gid=3352784"));

				final JLabel loveFeedbackAnimation =
						new JLabel(ImageManager.get().getImageIcon("images/window/we_love_community_and_feedback.gif"),
								JLabel.LEFT);
				loveFeedbackAnimation.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
				loveFeedbackAnimation.addMouseListener(new MouseAdapter() {
					@Override
					public void mouseClicked(final MouseEvent e) {
						forumActionListener.actionPerformed(null);
					}
				});

				final DCPanel innerPanel = new DCPanel();
				innerPanel.setLayout(new VerticalLayout());
				innerPanel.setBorder(new CompoundBorder(WidgetUtils.BORDER_LIST_ITEM_LEFT_ONLY,
						new EmptyBorder(0, adjuster.adjust(20), 0, 0)));
				innerPanel.add(editorPane);
				innerPanel.add(DCPanel.flow(tryProfessionalButton));
				innerPanel.add(Box.createVerticalStrut(adjuster.adjust(80)));
				innerPanel.add(loveFeedbackAnimation);
				innerPanel.add(Box.createVerticalStrut(adjuster.adjust(20)));
				innerPanel.add(DCPanel.flow(discussionForumButton, twitterButton, linkedInButton));
				innerPanel.add(Box.createVerticalStrut(5));

				result.setLayout(new VerticalLayout());
				result.add(Box.createVerticalStrut(adjuster.adjust(100)));
				result.add(innerPanel);
			}
		}

		return wrapContent(result);
	}

	private JComponent createButtonPanel() {
		final String newJobText = PropertyUtil.getProperty(SystemProperties.UI_DESKTOP_TEXT_NEW_JOB_BUTTON);
		//SystemProperties.getString(SystemProperties.UI_DESKTOP_TEXT_NEW_JOB_BUTTON, "Build new job");

		final JButton newJobButton = WidgetFactory.createPrimaryButton(newJobText, IconUtils.MODEL_JOB);
		newJobButton.addActionListener(e -> getWindow().changePanel(AnalysisWindowPanelType.SELECT_DS));

		final PopupButton recentJobsButton =
				WidgetFactory.createDefaultPopupButton(PropertyUtil.getProperty("datacleaner.ui.desktop.text.button.recentjob"), IconUtils.FILE_HOME_FOLDER);
		recentJobsButton.setMenuPosition(MenuPosition.TOP);
		recentJobsButton.addActionListener(e -> refreshRecentJobs(recentJobsButton));
		final JButton browseJobsButton = WidgetFactory.createDefaultButton(PropertyUtil.getProperty("datacleaner.ui.desktop.text.button.browsejob"), IconUtils.FILE_FOLDER);
		browseJobsButton.addActionListener(_openAnalysisJobActionListener);

		final JButton manageDatastoresButton =
				WidgetFactory.createDefaultButton(PropertyUtil.getProperty("datacleaner.ui.desktop.text.button.managedatastores"), IconUtils.GENERIC_DATASTORE_IMAGEPATH);
		manageDatastoresButton.addActionListener(e -> getWindow().changePanel(AnalysisWindowPanelType.MANAGE_DS));

		final DCPanel buttonPanel = new DCPanel();
		buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
		buttonPanel.add(newJobButton);
		buttonPanel.add(Box.createHorizontalStrut(adjuster.adjust(10)));
		buttonPanel.add(browseJobsButton);
		buttonPanel.add(Box.createHorizontalStrut(adjuster.adjust(10)));
		buttonPanel.add(recentJobsButton);
		buttonPanel.add(Box.createHorizontalStrut(adjuster.adjust(10)));
		buttonPanel.add(manageDatastoresButton);
		buttonPanel.setBorder(new EmptyBorder(0, 0, adjuster.adjust(20), 0));

		return wrapContent(buttonPanel);
	}

	private void refreshRecentJobs(final PopupButton recentJobsButton) {
		final List<FileObject> recentJobFiles = getRecentJobFiles();
		final JPopupMenu recentJobsMenu = recentJobsButton.getMenu();
		/*
		 * The menu is rebuild every time the user clicks on the menu, so the content is removed so that we do not have
		 * duplicates
		 */
		recentJobsMenu.removeAll();

		for (int i = 0; i < recentJobFiles.size(); i++) {
			final FileObject jobFile = recentJobFiles.get(i);
			final JMenuItem menuItem = new OpenAnalysisJobMenuItem(jobFile, _openAnalysisJobActionListener);
			recentJobsMenu.add(menuItem);
		}
	}

	private List<FileObject> getRecentJobFiles() {
		final List<FileObject> recentJobFiles = _userPreferences.getRecentJobFiles();
		final List<FileObject> result = new ArrayList<>();
		for (final FileObject fileObject : recentJobFiles) {
			try {
				if (fileObject.exists()) {
					result.add(fileObject);
					if (result.size() == 10) {
						break;
					}
				}
			} catch (final FileSystemException ex) {
				logger.debug("Skipping file {} because of unexpected error", ex);
			}
		}
		return result;
	}

}
